package edu.upb.acs.jobsmaps.activity.add;

import android.app.Activity;
import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import android.os.Bundle;
import android.speech.RecognizerIntent;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.*;
import edu.upb.acs.jobsmaps.R;
import edu.upb.acs.jobsmaps.database.task.AddJobTask;
import edu.upb.acs.jobsmaps.entity.CompanyIdentifier;
import edu.upb.acs.jobsmaps.entity.Job;
import edu.upb.acs.jobsmaps.util.Companies;
import edu.upb.acs.jobsmaps.voice.VoiceUtils;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;

public class AddJobActivityVoice extends Activity {
    private static final int VOICE_RECOGNITION_REQUEST_CODE = 1001;
    private static final String TAG = AddJobActivityVoice.class.getName();

    final private Context context = this;
    private Button addButton;

    //voice variables
    private EditText editBox;
    private Spinner spinner;
    private int flag;


    private Button mbtSpeakName;
    private Button mbtSpeakDescription;
    private Button mbtSpeakSalary;
    private Button mbtSpeakCompany;
    private Button mbtSpeakLatitude;
    private Button mbtSpeakLongitude;
    private Button mbtSpeakLink;
    private Button mbtSpeakPostedDate;


    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.addjobvoice);

        flag = 0;

        Log.d(TAG, "Initialize activity");

        //voice method -> Don't forget to add
        initializeVoiceData();

        System.out.println("done with spinner for good");

        // components from main.xml
        addButton = (Button) findViewById(R.id.EditJobButtonAdd);
        System.out.println("this is stupid");
        // add button listener
        addButton.setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View arg0) {

                createJob();

                AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(context);
                alertDialogBuilder.setMessage("Job was added with success");
                alertDialogBuilder.setCancelable(false).setPositiveButton("OK",
                        new DialogInterface.OnClickListener() {
                            public void onClick(DialogInterface dialog, int id) {
                                // when the ok button is pushed, return to main view
                                setResult(RESULT_OK);
                                finish();
                            }
                        }
                );

                // create alert dialog
                AlertDialog alertDialog = alertDialogBuilder.create();
                // show it
                alertDialog.show();
            }
        });

        Companies.populateSpinnerCompanies((Spinner) findViewById(R.id.addJobCompany), this);

        Button goBackButton = (Button) findViewById(R.id.EditJobButtonCancel);
        goBackButton.setOnClickListener(new OnClickListener() {
            public void onClick(View arg0) {
                goToMainActivity();
            }
        });
    }

    private void createJob() {
        final Job job = new Job();

        final EditText nameField = (EditText) findViewById(R.id.addJobName);
        String name = nameField.getText().toString();
        System.out.println("job name = >" + name + "<");
        job.setName(name);

        final EditText descField = (EditText) findViewById(R.id.addJobDescription);
        String description = descField.getText().toString();
        System.out.println("job description = >" + description + "<");
        job.setDescription(description);

        Spinner spinner = (Spinner) findViewById(R.id.addJobCompany);
        CompanyIdentifier value = (CompanyIdentifier) spinner.getSelectedItem();
        job.setCompanyId(String.valueOf(value.getId()));

        Double latitude = Double.valueOf(((EditText) findViewById(R.id.addJobLatitude)).getText().toString());
        job.setLatitude(latitude);

        Double longitude = Double.valueOf(((EditText) findViewById(R.id.addJobLongitude)).getText().toString());
        job.setLongitude(longitude);

        final EditText salaryField = (EditText) findViewById(R.id.addJobSalary);
        String salary = salaryField.getText().toString();
        System.out.println("job salary = >" + salary + "<");
        //TODO error handling: salary it's not a valid number
        if (salary != null && salary.length() > 0) {
            job.setSalary(Integer.valueOf(salary));
        }

        final EditText jobUrlField = (EditText) findViewById(R.id.addJobUrl);
        String jobUrl = jobUrlField.getText().toString();
        System.out.println("job url = >" + jobUrl + "<");
        job.setJobUrl(jobUrl);

		final EditText jobDateField = (EditText) findViewById(R.id.addJobPostedDate);
		String jobDate = jobDateField.getText().toString();
		System.out.println("job date = >" + jobDate + "<");
		try {
			Date date = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").parse(jobDate);
			job.setPostedDate(date);
		} catch (ParseException e) {
			Log.e(TAG, "Can not parse date", e);
		}

		job.setActive(true);

        AddJobTask addJobTask = new AddJobTask();
        try {
            Integer persistedJobId = addJobTask.execute(job).get();
            Log.d(TAG, "New job id = " + persistedJobId);
        } catch (Exception e) {
            Log.e(TAG, "Can not persist job", e);
        }
    }

    private void goToMainActivity() {
        setResult(RESULT_OK);
        finish();
    }


    //voice methods
    private void initializeVoiceData() {
        final Activity activity = this;

        mbtSpeakName = (Button) findViewById(R.id.buttonVoiceJob);
        mbtSpeakName.setOnClickListener(new View.OnClickListener() {
            public void onClick(View arg0) {
                editBox = (EditText) findViewById(R.id.addJobName);
                VoiceUtils.speak(null, null, activity);
                flag = 2;
            }
        });

        mbtSpeakDescription = (Button) findViewById(R.id.buttonVoiceDescription);
        mbtSpeakDescription.setOnClickListener(new View.OnClickListener() {
            public void onClick(View arg0) {
                editBox = (EditText) findViewById(R.id.addJobDescription);
                VoiceUtils.speak(null, null, activity);
                flag = 2;
            }
        });

        mbtSpeakCompany = (Button) findViewById(R.id.btnJobCompanyAddVoice);
        mbtSpeakCompany.setOnClickListener(new View.OnClickListener() {
            public void onClick(View arg0) {
                spinner = (Spinner) findViewById(R.id.addJobCompany);
                ArrayAdapter myAdap = (ArrayAdapter) spinner.getAdapter(); //cast to an ArrayAdapter
                int nrElements = myAdap.getCount();

                List<String> valuesSpinner = new ArrayList<>();
                for (int i = 0; i < nrElements; i++) {
                    valuesSpinner.add(spinner.getItemAtPosition(i).toString());
                }

                VoiceUtils.speak(null, valuesSpinner, activity);
                flag = 1;
            }
        });

        mbtSpeakLatitude = (Button) findViewById(R.id.btnJobLatitudeAddVoice);
        mbtSpeakLatitude.setOnClickListener(new View.OnClickListener() {
            public void onClick(View arg0) {
                editBox = (EditText) findViewById(R.id.addJobLatitude);
                VoiceUtils.speak(null, null, activity);
                flag = 2;
            }
        });

        mbtSpeakLongitude = (Button) findViewById(R.id.btnJobLongitudeVoice);
        mbtSpeakLongitude.setOnClickListener(new View.OnClickListener() {
            public void onClick(View arg0) {
                editBox = (EditText) findViewById(R.id.addJobLongitude);
                VoiceUtils.speak(null, null, activity);
                flag = 2;
            }
        });

        mbtSpeakSalary = (Button) findViewById(R.id.buttonVoiceSalary);
        mbtSpeakSalary.setOnClickListener(new View.OnClickListener() {
            public void onClick(View arg0) {
                editBox = (EditText) findViewById(R.id.addJobSalary);
                VoiceUtils.speak(null, null, activity);
                flag = 2;
            }
        });

        mbtSpeakLink = (Button) findViewById(R.id.buttonVoiceUrl);
        mbtSpeakLink.setOnClickListener(new View.OnClickListener() {
            public void onClick(View arg0) {
                editBox = (EditText) findViewById(R.id.addJobUrl);
                VoiceUtils.speak(null, null, activity);
                flag = 2;
            }
        });

        mbtSpeakPostedDate = (Button) findViewById(R.id.buttonVoicePostedDate);
        mbtSpeakPostedDate.setOnClickListener(new View.OnClickListener() {
            public void onClick(View arg0) {
                editBox = (EditText) findViewById(R.id.addJobPostedDate);
                VoiceUtils.speak(null, null, activity);
                flag = 2;
            }
        });

        checkVoiceRecognition();
    }

    public void checkVoiceRecognition() {
        // Check if voice recognition is present
        PackageManager pm = getPackageManager();
        List<ResolveInfo> activities = pm.queryIntentActivities(new Intent(
                RecognizerIntent.ACTION_RECOGNIZE_SPEECH), 0);
        if (activities.size() == 0) {
            mbtSpeakName.setEnabled(false);
            mbtSpeakDescription.setEnabled(false);
            mbtSpeakSalary.setEnabled(false);
            mbtSpeakCompany.setEnabled(false);
            mbtSpeakLatitude.setEnabled(false);
            mbtSpeakLongitude.setEnabled(false);
            mbtSpeakLink.setEnabled(false);
            mbtSpeakPostedDate.setEnabled(false);

            mbtSpeakName.setText("Voice recognizer not present");
            mbtSpeakDescription.setText("Voice recognizer not present");
            mbtSpeakSalary.setText("Voice recognizer not present");
            mbtSpeakCompany.setText("Voice recognizer not present");
            mbtSpeakLatitude.setText("Voice recognizer not present");
            mbtSpeakLongitude.setText("Voice recognizer not present");
            mbtSpeakLink.setText("Voice recognizer not present");
            mbtSpeakPostedDate.setText("Voice recognizer not present");

            Toast.makeText(this, "Voice recognizer not present",
                    Toast.LENGTH_SHORT).show();
        }
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        if (requestCode == VOICE_RECOGNITION_REQUEST_CODE)

            //If Voice recognition is successful then it returns RESULT_OK
            if (resultCode == RESULT_OK) {

                ArrayList<String> textMatchList = data
                        .getStringArrayListExtra(RecognizerIntent.EXTRA_RESULTS);

                if (!textMatchList.isEmpty()) {
                    Log.d(TAG, "FLAG IS: " + flag);
                    if (flag == 2) {
                        // populate the Matches
                        String enteredDate = textMatchList.get(0);
                        if (enteredDate.equalsIgnoreCase("today")) {
							SimpleDateFormat dt1 = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
							String date = dt1.format(new Date());
                            editBox.setText(date);
                        } else if (enteredDate.equalsIgnoreCase("yesterday")) {
                            Calendar c = Calendar.getInstance();
                            c.setTime(new Date());
                            c.add(Calendar.DATE, -1);  // number of days to add
                            Date yesterday = new Date(c.getTimeInMillis());
							SimpleDateFormat dt1 = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
							String date = dt1.format(yesterday);
                            editBox.setText(date);
                        } else {
                            editBox.setText(textMatchList.get(0));
                        }
                    } else if (flag == 1) {
                        ArrayAdapter myAdap = (ArrayAdapter) spinner.getAdapter(); //cast to an ArrayAdapter
                        int nrElements = myAdap.getCount();

                        List<String> valuesSpinner = new ArrayList<>();
                        for (int i = 0; i < nrElements; i++) {
                            valuesSpinner.add(spinner.getItemAtPosition(i).toString());
                        }

                        for (int i = 0; i < valuesSpinner.size(); i++) {
                            for (int j = 0; j < textMatchList.size(); j++) {
                                Log.d(TAG, "textMatchList: " + textMatchList.get(j));
                                if (valuesSpinner.get(i).equalsIgnoreCase(textMatchList.get(j))) {
                                    spinner.setSelection(i);
                                }
                            }
                        }
                    }
                }
                //Result code for various error.
            } else if (resultCode == RecognizerIntent.RESULT_AUDIO_ERROR) {
                showToastMessage("Audio Error");
            } else if (resultCode == RecognizerIntent.RESULT_CLIENT_ERROR) {
                showToastMessage("Client Error");
            } else if (resultCode == RecognizerIntent.RESULT_NETWORK_ERROR) {
                showToastMessage("Network Error");
            } else if (resultCode == RecognizerIntent.RESULT_NO_MATCH) {
                showToastMessage("No Match");
            } else if (resultCode == RecognizerIntent.RESULT_SERVER_ERROR) {
                showToastMessage("Server Error");
            }
        super.onActivityResult(requestCode, resultCode, data);
    }

    /**
     * Helper method to show the toast message
     */
    void showToastMessage(String message) {
        Toast.makeText(this, message, Toast.LENGTH_SHORT).show();
    }
}
